package xyz.tommy0607.codepedia_helper.action;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.actionSystem.PlatformDataKeys;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.ui.components.JBList;
import kotlin.Pair;
import okhttp3.FormBody;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import org.jetbrains.annotations.NotNull;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import xyz.tommy0607.codepedia_helper.Main;
import xyz.tommy0607.codepedia_helper.model.Annotation;

import javax.swing.*;
import java.io.IOException;

public class ShowAnnotationsAction extends AnAction {
    private int lineNumber = -1;

    public ShowAnnotationsAction() {
        super();
    }

    public ShowAnnotationsAction(int lineNumber) {
        this.lineNumber = lineNumber;
    }

    @Override
    public void update(@NotNull AnActionEvent e) {
        Project project = e.getProject();
        e.getPresentation().setEnabledAndVisible(project != null
                && Main.getInstance(project) != null && Main.getInstance(project).hasLogin);
    }

    @Override
    public void actionPerformed(@NotNull AnActionEvent event) {
        if (lineNumber == -1) {
            //from the popup menu
            final Editor editor = event.getData(CommonDataKeys.EDITOR);
            lineNumber = editor.getCaretModel().getLogicalPosition().line + 1;
        }
        Project project = event.getProject();
        VirtualFile currentFile = event.getData(PlatformDataKeys.VIRTUAL_FILE);
        Integer fileID = currentFile.getUserData(Main.FILE_ID_KEY);
        if (fileID != null) new Thread(() -> {
            try {
                RequestBody requestBody = new FormBody.Builder()
                        .add("file_id", fileID.toString())
                        .add("line_num", String.valueOf(lineNumber))
                        .build();

                Request request = new Request.Builder()
                        .url("http://codepedia.trustie.net/operations/show_annotation/")
                        .addHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8")
                        .addHeader("Cookie", "sessionid=" + Main.getInstance(project).sessionID)
                        .post(requestBody)
                        .build();
                Response response = Main.getInstance(project).okHttpClient.newCall(request).execute();
                JSONObject json = JSON.parseObject(response.body().string());
                String html = json.getString("html_str");
                Annotation[] annos = null;
                int totalAnnosCount = 0;
                if (html != null && !html.equals("")) {
                    Pair<Integer, Annotation[]> pair = parseHTML(lineNumber, html);
                    annos = pair.component2();
                    totalAnnosCount = pair.component1();
                }
                final Annotation[] annosFinal = annos;
                final int totalAnnosCountFinal = totalAnnosCount;
                ApplicationManager.getApplication().invokeLater(() -> {
                    ShowAnnotationsDialog dialog = new ShowAnnotationsDialog(totalAnnosCountFinal, annosFinal);
                    dialog.show();
                });
            } catch (IOException e) {
                e.printStackTrace();
            }
        }).start();

    }

    public Pair<Integer, Annotation[]> parseHTML(int lineNumber, String html) {
        Document document = Jsoup.parse(html);
        Element titleNode = document.select(".ques-title").get(0);
        String title = titleNode.text();
        int index = title.indexOf("有");
        int annosCount = Integer.parseInt(title.substring(index + 1, index + 2));
        Elements contents = document.select(".parthalf_con");
        Annotation[] annotations = new Annotation[contents.size()];
        for (int i = 0; i < contents.size(); i++) {
            annotations[i] = new Annotation();
            annotations[i].lineNumber = lineNumber;
            String content = contents.get(i).getAllElements().get(1).text().trim();
            if (content.charAt(1) == '.') content = content.substring(3);
            annotations[i].content = content;
        }

        Elements authors = document.select("span.fr");
        for (int i = 0; i < contents.size(); i++) {
            annotations[i].author = authors.get(i).text();
        }

        for (int i = 0; i < contents.size(); i++) {
            System.out.println(annotations[i]);
        }
        System.out.println(annosCount);
        return new Pair<>(annosCount, annotations);
    }


    class ShowAnnotationsDialog extends DialogWrapper {

        private Annotation[] annos;

        public ShowAnnotationsDialog(int totalAnnosCount, Annotation[] annos) {
            super(true);
            init();
            this.annos = annos;
            setTitle(String.format("Totally %d annotation(s) at this line", totalAnnosCount));
        }

        @Override
        protected JComponent createCenterPanel() {
            JBList<Annotation> annosList = new JBList<>();
            annosList.setCellRenderer((list, value, index, isSelected, cellHasFocus) -> {
                JLabel label = new JLabel();
                label.setText(value.content);
                return label;
            });
            if (annos != null) annosList.setListData(annos);
            return annosList;
        }

        @NotNull
        @Override
        protected Action[] createActions() {
            return new Action[]{getOKAction()};
        }
    }
}
